#include "../include/user_dao.h"
#include <cppconn/prepared_statement.h>
#include <cppconn/resultset.h>
#include "nlohmann/json.hpp"

std::shared_ptr<mysqlConnection> user_dao::new_get_con()
{
    return pool.get_con();
}

void user_dao::new_return_con(std::shared_ptr<mysqlConnection>&con){
    pool.return_con(con);

}


struct search_user_res user_dao::search_user(const std::string &from_user_email,const std::string &tar_user_email)
{
    auto mysql_con=pool.get_con();  //这个是必定能拿到连接的，不够会去创建
    mysql_con->_con->setAutoCommit(false);

    auto pre_stm=mysql_con->_con->prepareStatement("select user_name from user where email=?");
    pre_stm->setString(1,tar_user_email);
    

    auto res=pre_stm->executeQuery();
    struct search_user_res search_res;
    //由于最多只有一行数据，所以
    std::string tar_user_name;
    if(res->next()){
        search_res.tar_user_name=res->getString("user_name");
    }else{
        search_res.tar_user_name="";
        delete res;
        delete pre_stm;
        goto ending;
        
    }

    delete res;
    delete pre_stm;

    

    //如果目标用户存在，那么判断关系
    pre_stm=mysql_con->_con->prepareStatement("select id from friend_list where user_email=? and friend_email=?");
    pre_stm->setString(1,from_user_email);
    pre_stm->setString(2,tar_user_email);
    res=pre_stm->executeQuery();
    if(res->next()){
        search_res.is_already_friend=true;
    }else{
        search_res.is_already_friend=false;
    }

    delete res;
    delete pre_stm;


ending:
    mysql_con->_con->setAutoCommit(true);
    mysql_con->_con->commit();
    pool.return_con(mysql_con);

    std::cout<<"成功执行search_user"<<std::endl;
    return search_res;
   
}

bool user_dao::friend_apply_is_repeat(std::shared_ptr<mysqlConnection> &mysql_con,const std::string &from_email,const std::string &to_email){

    //这里的查询结果是为了使用索引覆盖，避免回表
    auto pre_stmt=mysql_con->_con->prepareStatement("select from_email from apply_list where from_email=? and to_email=?");
    pre_stmt->setString(1,to_email);
    pre_stmt->setString(2,from_email);
    auto res=pre_stmt->executeQuery();
    if(res->next()){
        //如果存在，那么返回true即可
        delete res;
        delete pre_stmt;
        return true;
    }
    delete res;
    delete pre_stmt;

    return false;




}


bool user_dao::add_friend_apply(std::shared_ptr<mysqlConnection> &mysql_con,const std::string &from_email, const std::string &to_email,const std::string&varify_text)
{
    

    auto pre_stmt=mysql_con->_con->prepareStatement("insert into apply_list(from_email,to_email,status,varify_text,apply_res) values(?,?,0,?,0)");
    pre_stmt->setString(1,from_email);
    pre_stmt->setString(2,to_email);
    pre_stmt->setString(3,varify_text);

    int row_affecteds=pre_stmt->executeUpdate();
    if(row_affecteds==1){
        delete pre_stmt;
        return true;
    }
    //走到这里表示from_email与to_email已经存在
    delete pre_stmt;
    return false;
}


int user_dao::modify_apply_list(std::shared_ptr<mysqlConnection> &mysql_con,const std::string &from_email, const std::string &to_email, const int &apply_res)
{

    
    auto pre_stmt=mysql_con->_con->prepareStatement("update apply_list set status=?,apply_res=? where from_email=? and to_email=? and status=0");
    pre_stmt->setInt(1,1);
    pre_stmt->setInt(2,apply_res);
    pre_stmt->setString(3,from_email);
    pre_stmt->setString(4,to_email);

    int affect_rows=pre_stmt->executeUpdate();
    
    delete pre_stmt;

    return affect_rows;
 
}


int user_dao::add_friend_list(std::shared_ptr<mysqlConnection> &mysql_con,const std::string &from_email, const std::string &to_email)
{
    

    auto pre_stmt=mysql_con->_con->prepareStatement("insert into friend_list(user_email,friend_email) values(?,?)");
    pre_stmt->setString(1,from_email);
    pre_stmt->setString(2,to_email);
    int affect_rows=pre_stmt->executeUpdate();
    if(affect_rows!=1){
        std::cout<<"添加好友时，插入数据居然失败---1"<<std::endl;
        delete pre_stmt;
        return -1;
    }
    pre_stmt->setString(1,to_email);
    pre_stmt->setString(2,from_email);
    affect_rows=pre_stmt->executeUpdate();  //双向添加了
    if(affect_rows!=1){
        std::cout<<"添加好友时，插入数据居然失败---1"<<std::endl;
        delete pre_stmt;
        return -1;
    }


    delete pre_stmt;

    return 0;
}

void user_dao::search_friend_list(std::shared_ptr<mysqlConnection> &mysql_con,const std::string &user_email,nlohmann::json &user_info_json){
    auto pre_stmt=mysql_con->_con->prepareStatement("select user.email as _email, user.user_name as _name from friend_list left join user on friend_list.friend_email=user.email "
       "where friend_list.user_email=? ");
    pre_stmt->setString(1,user_email);
     
    auto res=pre_stmt->executeQuery();
    while(res->next()){
        nlohmann::json friend_item_json;
        friend_item_json["user_email"]=res->getString("_email");
        friend_item_json["user_name"]=res->getString("_name");
        user_info_json["user_list"].push_back(friend_item_json);
    }
    delete res;
    delete pre_stmt;

}

void user_dao::search_apply_list_from_self(std::shared_ptr<mysqlConnection> &mysql_con, const std::string &user_email, nlohmann::json &user_info_json)
{
    auto pre_stmt=mysql_con->_con->prepareStatement("select user.email as _email,user.user_name as _user_name,apply_list.status as _status, "
        " apply_list.varify_text as _varify_text,apply_list.apply_res as _apply_res "
        " from apply_list left join user on apply_list.to_email=user.email "
        " where apply_list.from_email=? ");
    pre_stmt->setString(1,user_email);    
    auto res=pre_stmt->executeQuery(); 
    while(res->next()){
        nlohmann::json apply_list_from_self_item;
        apply_list_from_self_item["user_email"]=res->getString("_email");
        apply_list_from_self_item["user_name"]=res->getString("_user_name");
        apply_list_from_self_item["status"]=res->getInt("_status");
        apply_list_from_self_item["varify_text"]=res->getString("_varify_text");
        apply_list_from_self_item["apply_res"]=res->getInt("_apply_res");
        user_info_json["apply_list_from_self"].push_back(apply_list_from_self_item);
    }

    delete res;
    delete pre_stmt;


}

void user_dao::search_apply_list_from_other(std::shared_ptr<mysqlConnection> &mysql_con, const std::string &user_email, nlohmann::json &user_info_json)
{
    auto pre_stmt=mysql_con->_con->prepareStatement("select user.email as _email,user.user_name as _user_name,apply_list.status as _status, "
        " apply_list.varify_text as _varify_text,apply_list.apply_res as _apply_res "
        " from apply_list left join user on apply_list.from_email=user.email "
        " where apply_list.to_email=? ");
    pre_stmt->setString(1,user_email);    
    auto res=pre_stmt->executeQuery(); 
    while(res->next()){
        nlohmann::json apply_list_from_other_item;
        apply_list_from_other_item["user_email"]=res->getString("_email");
        apply_list_from_other_item["user_name"]=res->getString("_user_name");
        apply_list_from_other_item["status"]=res->getInt("_status");
        apply_list_from_other_item["varify_text"]=res->getString("_varify_text");
        apply_list_from_other_item["apply_res"]=res->getInt("_apply_res");
        user_info_json["apply_list_from_other"].push_back(apply_list_from_other_item);
    }
    
    delete res;
    delete pre_stmt;    

}

void user_dao::insert_message(std::shared_ptr<mysqlConnection> &mysql_con, const std::string &from_email, const std::string &to_email, const int &msg_type, const std::string &msg_id, const std::string msg_data)
{
    //这里默认status就为0就好了:表示没有消费掉
    auto pre_stmt=mysql_con->_con->prepareStatement("insert into message(from_email,to_email,msg_type,msg_id,msg_data,status) values(?,?,?,?,?,0) ");
    pre_stmt->setString(1,from_email);
    pre_stmt->setString(2,to_email);
    pre_stmt->setInt(3,msg_type);
    pre_stmt->setString(4,msg_id);
    pre_stmt->setString(5,msg_data);
    int affected_rows=pre_stmt->executeUpdate();
    if(affected_rows!=1){
        std::cout<<"持久化文本数据时，返回的affected_rows:"<<affected_rows<<"这不对吧  "<<std::endl;
    }
    delete pre_stmt;
}




